//
//  LZChangeFunctionName.m
//  LZSpamCode
//
//  Created by ZengLiZhi on 2024/6/26.
//

#import "LZChangeFunctionName.h"
#import "LZSpamCodeManager.h"
#import "LZFileManager.h"
#import "LZStringRandom.h"


@implementation LZChangeFunctionName

+ (void)start{
    
    [self openVerbsTxt];
    //查找文件
    @autoreleasepool {
        [self changeFunctionNameInDirectory:[LZSpamCodeManager shareInstance].gSourceCodeDir];
    }
    //查找文件类
    //查找类的方法
    //获取方法名
    //搜索类引用及对象
    //修改
    NSLog(@"\n\n修改方法名完成\n\n");
}

#pragma mark - 修改方法名
+ (void)changeFunctionNameInDirectory:(NSString *)directory{
    
    NSArray *ignorFuncPrefix = @[@"init"];
    
    NSFileManager *fm = [NSFileManager defaultManager];
    NSArray<NSString *> *files = [fm contentsOfDirectoryAtPath:directory error:nil];
    BOOL isDirectory;
    for (NSString *fileName in files) {
        if ([[LZSpamCodeManager shareInstance].gIgnoreDirNames containsObject:fileName]) continue;
        NSString *filePath = [directory stringByAppendingPathComponent:fileName];
        if ([fm fileExistsAtPath:filePath isDirectory:&isDirectory] && isDirectory) {
            [self changeFunctionNameInDirectory:filePath];
            continue;
        }
        //        if (![fileName hasSuffix:@".h"] && ![fileName hasSuffix:@".m"] && ![fileName hasSuffix:@".mm"] && ![fileName hasSuffix:@".swift"]) continue;
        if (![fileName hasSuffix:@".m"] || [fileName containsString:@"+"] || [fileName containsString:@"base"]) {
            //目前只支持.m .h文件
            // base 基类方法暂时不支持，会影响子类调用
            continue;
        }
        
        
        //        NSMutableString *fileContent = [LZFileManager stringWithContentsOfFile:filePath];
        
        NSString *mFilePath = filePath;
        NSString *hFilePath = [mFilePath.stringByDeletingPathExtension stringByAppendingPathExtension:@"h"];
        isDirectory = NO;
        if (![fm fileExistsAtPath:hFilePath isDirectory:&isDirectory]) {
            //不存在同名.h文件,跳过
            continue;
        }
        
        NSMutableString *mFileContent = [LZFileManager stringWithContentsOfFile:mFilePath];
        //表达式 "((?!\bstop\b).)+" 在匹配 "fdjka ljfdl stop fjdsla fdj" 时 ，将从头一直匹配到 "stop" 之前的位置，如果字符串中没有 "stop"，则匹配整个字符串。
        //@implementation \w+(((?!\b@end\b).)+\n*.*)*\s*@end
        NSString *regexStr_implementation = @" *@implementation \\w+(((?!\\bend\\b).)+\\n*.*)*\\s*@end";
//        NSString *regexStr_implementation = @" *@implementation +(\\w+)[^(]*\\n(?:.|\\n)+?@end";
        NSArray<NSTextCheckingResult *> *matches_implementation = [self findResultWithRegex:regexStr_implementation fileContent:mFileContent options:NSRegularExpressionUseUnicodeWordBoundaries];
        
        NSMutableString *hFileContent = [LZFileManager stringWithContentsOfFile:hFilePath];
        
        if (matches_implementation.count){
            NSLog(@"\n");
            NSLog(@"=================");
            NSLog(@"在文件：%@中，存在多个实现了方法的implementation: ",fileName);
            [matches_implementation enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull impResult, NSUInteger idx, BOOL * _Nonnull stop) {
                /** 匹配的代码块
                 @implementation MiaoBiToolModel
                 - (void)setInteractiveType:(NSInteger)interactiveType{
                     _skipType = interactiveType;
                     
                     _interactiveType = interactiveType;
                 }
                 @end
                 */
                NSString *implementationContent = [mFileContent substringWithRange:[impResult rangeAtIndex:0]];
//                NSLog(@"%@",implementationContent);
                //匹配没有实现任何方法的，可以跳过
                NSString *regexStr_empty = @"@implementation \\w+\\s*@end";
                NSArray<NSTextCheckingResult *> *matches_empty = [self findResultWithRegex:regexStr_empty fileContent:implementationContent options:NSRegularExpressionUseUnicodeWordBoundaries];
                if (matches_empty.count == 0) {
                    NSString *regexStr_className = @"@implementation \\w+";
                    NSArray<NSTextCheckingResult *> *matches_className = [self findResultWithRegex:regexStr_className fileContent:implementationContent options:NSRegularExpressionUseUnicodeWordBoundaries];
                    if (matches_className.count) {
                        NSString *string = [implementationContent substringWithRange:[matches_className.firstObject rangeAtIndex:0]];
                        NSArray *arr = [string componentsSeparatedByString:@" "];
                        if (arr.count) {
                            NSString *className = [arr lastObject];
                            NSLog(@"%@",className);
                            
                            if ([className.lowercaseString containsString:@"base"]) {
                                return;
                            }
                            
                            // 如果该类型没有公开，只在 .m 文件中使用，则不处理
                            NSString *regexStr_className = [NSString stringWithFormat:@"\\b%@\\b", className];
                            NSRange range_className = [hFileContent rangeOfString:regexStr_className options:NSRegularExpressionSearch];
                            if (range_className.location != NSNotFound) {
                                // 查找方法
                                NSString *implementation = [mFileContent substringWithRange:impResult.range];
                                
                                NSString *regexStr_func = @" *([-+])[^)]+\\)([^;{]+)";
                                NSArray<NSTextCheckingResult *> *matches_func = [self findResultWithRegex:regexStr_func fileContent:implementation options:NSRegularExpressionAnchorsMatchLines|NSRegularExpressionUseUnicodeWordBoundaries];
                                
                                //遍历找到的方法名
                                [matches_func enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull matche, NSUInteger idx, BOOL * _Nonnull stop) {
                                    
                                    NSString *methodName = [[implementation substringWithRange:[matche rangeAtIndex:2]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
                                    //                if ([[LZSpamCodeManager shareInstance].gIgnoreDirNames containsObject:methodName]) continue;
                                    
                                    if ([hFileContent containsString:methodName] && [methodName containsString:@":"]) {
                                        
                                        // - (void)handlerConfigDic:(NSDictionary *)configDic
                                        
                                        // 查找.h中这个方法
                                        //                        NSRegularExpression *expression_func_h = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"\\b%@\\b", methodName] options:NSRegularExpressionAnchorsMatchLines|NSRegularExpressionUseUnicodeWordBoundaries error:nil];
                                        //                        NSArray<NSTextCheckingResult *> *matches_func_h = [expression_func_h matchesInString:hFileContent options:0 range:NSMakeRange(0, hFileContent.length)];
                                        /// .h文件中也有这个方法
                                        if ([hFileContent containsString:methodName]){
                                            // - (void)handlerConfigDic
                                            NSString *str1 = [methodName componentsSeparatedByString:@":"].firstObject;
                                            // handlerConfigDic
                                            NSString *oldFuncNamePrefix = [str1 componentsSeparatedByString:@")"].lastObject;
                                            
                                            BOOL isIgnor = NO;
                                            for (NSString *ignorPrefix in ignorFuncPrefix) {
                                                if ([oldFuncNamePrefix hasPrefix:ignorPrefix]) {
                                                    isIgnor = YES;
                                                }
                                            }
                                            
                                            if (!isIgnor) {
                                                NSString *newFuncNamePrefix = [self randomNewFuncName];
                                                
                                                NSString *oldFuncNamePrefix1 = [NSString stringWithFormat:@")%@:",oldFuncNamePrefix];
                                                NSString *newFuncNamePrefix1 = [NSString stringWithFormat:@")%@:",newFuncNamePrefix];
                                                
                                                NSString *oldFuncNamePrefix2 = [NSString stringWithFormat:@"self %@:",oldFuncNamePrefix];
                                                NSString *newFuncNamePrefix2 = [NSString stringWithFormat:@"self %@:",newFuncNamePrefix];
                                                
                                                NSString *oldFuncNamePrefix3 = [NSString stringWithFormat:@"[self class] %@:",oldFuncNamePrefix];
                                                NSString *newFuncNamePrefix3 = [NSString stringWithFormat:@"[self class] %@:",newFuncNamePrefix];
                                                
                                                NSString *oldFuncNamePrefix4 = [NSString stringWithFormat:@"[%@ shareInstance] %@:",className,oldFuncNamePrefix];
                                                NSString *newFuncNamePrefix4 = [NSString stringWithFormat:@"[%@ shareInstance] %@:",className,newFuncNamePrefix];
                                                
                                                NSString *oldFuncNamePrefix5 = [NSString stringWithFormat:@"[%@ %@:",className,oldFuncNamePrefix];
                                                NSString *newFuncNamePrefix5 = [NSString stringWithFormat:@"[%@ %@:",className,newFuncNamePrefix];
                                                
                                                NSArray *oldArr = @[oldFuncNamePrefix1,oldFuncNamePrefix2,oldFuncNamePrefix3,oldFuncNamePrefix4,oldFuncNamePrefix5];
                                                NSArray *newArr = @[newFuncNamePrefix1,newFuncNamePrefix2,newFuncNamePrefix3,newFuncNamePrefix4,newFuncNamePrefix5];
                                                // 替换为新方法名
                                                //修改这个类.h和.m文件
                                                for (int i = 0; i < oldArr.count; i++) {
                                                    NSString *oldFuncNamePrefix = oldArr[i];
                                                    NSString *newFuncNamePrefix = newArr[i];
                                                    
                                                    [hFileContent replaceOccurrencesOfString:oldFuncNamePrefix withString:newFuncNamePrefix options:NSCaseInsensitiveSearch range:NSMakeRange(0, hFileContent.length)];
                                                    [mFileContent replaceOccurrencesOfString:oldFuncNamePrefix withString:newFuncNamePrefix options:NSCaseInsensitiveSearch range:NSMakeRange(0, mFileContent.length)];
                                                }
                                                
                                                //改项目中其他地方引用的
                                                [self replaceNewFuncNameWithClassName:className oldFuncNamePrefix:oldFuncNamePrefix newFuncNamePrefix:newFuncNamePrefix InDirectory:[LZSpamCodeManager shareInstance].gSourceCodeDir currentFile:mFilePath];
                                            }
                                            
                                        }
                                        
                                        
                                    } else {
                                        
                                    }
                                    
                                }];
                            }
                        }else{
                            NSLog(@"string:%@ 未匹配className",string);
                        }
                    }
                }
                
                
                
            }];
            NSLog(@"=================");
            NSLog(@"\n");
        }
//        if (matches_implementation.count != 1) continue; //目前只支持含有一个@implementation的
        
        
        /*
        [matches_implementation enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull impResult, NSUInteger idx, BOOL * _Nonnull stop) {
            
            //            NSMutableString *implementation = fileContent;
            
            NSString *className = [mFileContent substringWithRange:[impResult rangeAtIndex:1]];
            if ([className.lowercaseString containsString:@"base"]) {
                return;
            }
            
            // 如果该类型没有公开，只在 .m 文件中使用，则不处理
            NSString *regexStr_className = [NSString stringWithFormat:@"\\b%@\\b", className];
            NSRange range_className = [hFileContent rangeOfString:regexStr_className options:NSRegularExpressionSearch];
            if (range_className.location != NSNotFound) {
                // 查找方法
                NSString *implementation = [mFileContent substringWithRange:impResult.range];
                
                NSString *regexStr_func = @" *([-+])[^)]+\\)([^;{]+)";
                NSArray<NSTextCheckingResult *> *matches_func = [self findResultWithRegex:regexStr_func fileContent:implementation options:NSRegularExpressionAnchorsMatchLines|NSRegularExpressionUseUnicodeWordBoundaries];
                
                //遍历找到的方法名
                [matches_func enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull matche, NSUInteger idx, BOOL * _Nonnull stop) {
                    
                    NSString *methodName = [[implementation substringWithRange:[matche rangeAtIndex:2]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
                    //                if ([[LZSpamCodeManager shareInstance].gIgnoreDirNames containsObject:methodName]) continue;
                    
                    if ([hFileContent containsString:methodName] && [methodName containsString:@":"]) {
                        
                        // - (void)handlerConfigDic:(NSDictionary *)configDic
                        
                        // 查找.h中这个方法
                        //                        NSRegularExpression *expression_func_h = [NSRegularExpression regularExpressionWithPattern:[NSString stringWithFormat:@"\\b%@\\b", methodName] options:NSRegularExpressionAnchorsMatchLines|NSRegularExpressionUseUnicodeWordBoundaries error:nil];
                        //                        NSArray<NSTextCheckingResult *> *matches_func_h = [expression_func_h matchesInString:hFileContent options:0 range:NSMakeRange(0, hFileContent.length)];
                        /// .h文件中也有这个方法
                        if ([hFileContent containsString:methodName]){
                            // - (void)handlerConfigDic
                            NSString *str1 = [methodName componentsSeparatedByString:@":"].firstObject;
                            // handlerConfigDic
                            NSString *oldFuncNamePrefix = [str1 componentsSeparatedByString:@")"].lastObject;
                            
                            BOOL isIgnor = NO;
                            for (NSString *ignorPrefix in ignorFuncPrefix) {
                                if ([oldFuncNamePrefix hasPrefix:ignorPrefix]) {
                                    isIgnor = YES;
                                }
                            }
                            
                            if (!isIgnor) {
                                NSString *newFuncNamePrefix = [self randomNewFuncName];
                                
                                NSString *oldFuncNamePrefix1 = [NSString stringWithFormat:@")%@:",oldFuncNamePrefix];
                                NSString *newFuncNamePrefix1 = [NSString stringWithFormat:@")%@:",newFuncNamePrefix];
                                
                                NSString *oldFuncNamePrefix2 = [NSString stringWithFormat:@"self %@:",oldFuncNamePrefix];
                                NSString *newFuncNamePrefix2 = [NSString stringWithFormat:@"self %@:",newFuncNamePrefix];
                                
                                NSString *oldFuncNamePrefix3 = [NSString stringWithFormat:@"[self class] %@:",oldFuncNamePrefix];
                                NSString *newFuncNamePrefix3 = [NSString stringWithFormat:@"[self class] %@:",newFuncNamePrefix];
                                
                                NSString *oldFuncNamePrefix4 = [NSString stringWithFormat:@"[%@ shareInstance] %@:",className,oldFuncNamePrefix];
                                NSString *newFuncNamePrefix4 = [NSString stringWithFormat:@"[%@ shareInstance] %@:",className,newFuncNamePrefix];
                                
                                NSString *oldFuncNamePrefix5 = [NSString stringWithFormat:@"[%@ %@:",className,oldFuncNamePrefix];
                                NSString *newFuncNamePrefix5 = [NSString stringWithFormat:@"[%@ %@:",className,newFuncNamePrefix];
                                
                                NSArray *oldArr = @[oldFuncNamePrefix1,oldFuncNamePrefix2,oldFuncNamePrefix3,oldFuncNamePrefix4,oldFuncNamePrefix5];
                                NSArray *newArr = @[newFuncNamePrefix1,newFuncNamePrefix2,newFuncNamePrefix3,newFuncNamePrefix4,newFuncNamePrefix5];
                                // 替换为新方法名
                                //修改这个类.h和.m文件
                                for (int i = 0; i < oldArr.count; i++) {
                                    NSString *oldFuncNamePrefix = oldArr[i];
                                    NSString *newFuncNamePrefix = newArr[i];
                                    
                                    [hFileContent replaceOccurrencesOfString:oldFuncNamePrefix withString:newFuncNamePrefix options:NSCaseInsensitiveSearch range:NSMakeRange(0, hFileContent.length)];
                                    [mFileContent replaceOccurrencesOfString:oldFuncNamePrefix withString:newFuncNamePrefix options:NSCaseInsensitiveSearch range:NSMakeRange(0, mFileContent.length)];
                                }
                                
                                //改项目中其他地方引用的
                                [self replaceNewFuncNameWithClassName:className oldFuncNamePrefix:oldFuncNamePrefix newFuncNamePrefix:newFuncNamePrefix InDirectory:[LZSpamCodeManager shareInstance].gSourceCodeDir currentFile:mFilePath];
                            }
                            
                        }
                        
                        
                    } else {
                        
                    }
                    
                }];
            }
            
        }];
         */
        
        [LZFileManager writeContent:hFileContent toFile:hFilePath];
        [LZFileManager writeContent:mFileContent toFile:mFilePath];
    }
}

+ (void)replaceNewFuncNameWithClassName:(NSString *)className oldFuncNamePrefix:(NSString *)oldFuncNamePrefix newFuncNamePrefix:(NSString *)newFuncNamePrefix InDirectory:(NSString *)directory currentFile:(NSString *)currentFile{
    
    //判断包含类名
    NSFileManager *fm = [NSFileManager defaultManager];
    NSArray<NSString *> *files = [fm contentsOfDirectoryAtPath:directory error:nil];
    BOOL isDirectory;
    for (NSString *fileName in files) {
        //        if ([[LZSpamCodeManager shareInstance].gIgnoreDirNames containsObject:fileName]) continue;
        NSString *filePath = [directory stringByAppendingPathComponent:fileName];
        
        if ([filePath isEqualToString:currentFile]) {
            continue;
        }
        
        if ([fm fileExistsAtPath:filePath isDirectory:&isDirectory] && isDirectory) {
            [self replaceNewFuncNameWithClassName:className oldFuncNamePrefix:oldFuncNamePrefix newFuncNamePrefix:newFuncNamePrefix InDirectory:filePath currentFile:currentFile];
            continue;
        }
        //        if (![fileName hasSuffix:@".h"] && ![fileName hasSuffix:@".m"] && ![fileName hasSuffix:@".mm"] && ![fileName hasSuffix:@".swift"]) continue;
        
        if ([fileName hasSuffix:@".h"]) {
            // header文件里面的宏定义可能用到了
            NSString *mFilePath = [filePath.stringByDeletingPathExtension stringByAppendingPathExtension:@"m"];
            isDirectory = NO;
            if (![fm fileExistsAtPath:mFilePath isDirectory:&isDirectory] && !isDirectory) {
                /// 不存在同名.m文件,且不是文件夹
                /// 说明这是header文件
                NSMutableString *hFileContent = [LZFileManager stringWithContentsOfFile:filePath];
                
                [self replaceInstanceFuncNameWithInstanceName:className
                                                  fileContent:hFileContent
                                            oldFuncNamePrefix:oldFuncNamePrefix
                                            newFuncNamePrefix:newFuncNamePrefix];
                [LZFileManager writeContent:hFileContent toFile:filePath];
            }
            continue;
        }
        
        if (![fileName hasSuffix:@".m"]) {
            //只有.m 文件里才会有使用 但是.h文件里可能有引用
            continue;
        }
        
        
        //判断是否包含类名、方法名
        NSString *mFilePath = filePath;
        NSString *hFilePath = [mFilePath.stringByDeletingPathExtension stringByAppendingPathExtension:@"h"];
        isDirectory = NO;
        if (![fm fileExistsAtPath:hFilePath isDirectory:&isDirectory]) {
            //不存在同名.h文件,跳过
            continue;
        }
        
        NSMutableString *mFileContent = [LZFileManager stringWithContentsOfFile:mFilePath];
        NSMutableString *hFileContent = [LZFileManager stringWithContentsOfFile:hFilePath];
        
        if (![hFileContent containsString:className] && ![mFileContent containsString:className]) {
            //判断是否是子类，子类中父类的属性对象调用其方法，会没有引用，那么.h和.m文件中可能不会有类名。
            //例如，父类的ViewModel，在子类调用。
//            NSString *superClassFilePath = [self findSuperClassFilePathWithClassName:className hFileContent:hFileContent];
//            if (!superClassFilePath) {
//                //.h和.m 文件里都没有包含类名,说明这个文件没有使用这个类,跳过
//                continue;
//            }
            continue;
        }
        
        NSString *regexStr_property = [NSString stringWithFormat:@"@property\\s+\\(.+%@.+;",className];
        
        //匹配的对象列表
        NSMutableArray *instanceArray = [NSMutableArray array];
        
        if ([hFileContent containsString:className]) {
            
            NSArray<NSTextCheckingResult *> *matches_property = [self findResultWithRegex:regexStr_property fileContent:hFileContent options:NSRegularExpressionUseUnicodeWordBoundaries];
            
            if (matches_property){
                
                //遍历找到的属性名
                [matches_property enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull matche, NSUInteger idx, BOOL * _Nonnull stop) {
                    
                    NSRange matchRange = [matche range];
                    NSString *matchedString = [hFileContent substringWithRange:matchRange];
                    NSLog(@"matches_property Found match: %@", matchedString);
                    //@property (nonatomic, strong) NSString    *   gProjectPath;
                    
                    NSArray *arr1 = [matchedString componentsSeparatedByString:@"*"];
                    if (arr1.count) {
                        NSString *propertyName = [arr1.lastObject stringByReplacingOccurrencesOfString:@" " withString:@""];
                        propertyName = [arr1.lastObject stringByReplacingOccurrencesOfString:@";" withString:@""];
                        NSLog(@"find property: %@ * %@", className,propertyName);
                        if (![instanceArray containsObject:propertyName]) {
                            [instanceArray addObject:propertyName];
                        }
                    }
                }];
            }
            
            
        }
        
        if ([mFileContent containsString:className]) {
            
            NSArray<NSTextCheckingResult *> *matches_property = [self findResultWithRegex:regexStr_property fileContent:mFileContent options:NSRegularExpressionUseUnicodeWordBoundaries];
            if (matches_property){
                
                //遍历找到的属性名
                [matches_property enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull matche, NSUInteger idx, BOOL * _Nonnull stop) {
                    
                    NSRange matchRange = [matche range];
                    NSString *matchedString = [mFileContent substringWithRange:matchRange];
                    NSLog(@"m文件: %@", matchedString);
                    //@property (nonatomic, strong) NSString    *   gProjectPath;
                    
                    NSArray *arr1 = [matchedString componentsSeparatedByString:@"*"];
                    if (arr1.count) {
                        NSString *propertyName = [arr1.lastObject stringByReplacingOccurrencesOfString:@" " withString:@""];
                        propertyName = [arr1.lastObject stringByReplacingOccurrencesOfString:@";" withString:@""];
                        NSLog(@"m文件 property: %@ * %@", className,propertyName);
                        if (![instanceArray containsObject:propertyName]) {
                            [instanceArray addObject:propertyName];
                        }
                    }
                }];
            }
            
            /// 局部变量
//            NSString *regexStr_sub_property = [NSString stringWithFormat:@"%@\\s{0,2}.+\\s{0,2};",className];
            NSString *regexStr_sub_property = [NSString stringWithFormat:@"%@\\s*\\*\\s*[a-zA-Z0-9_]+",className];
            NSArray<NSTextCheckingResult *> *matches_sub_property = [self findResultWithRegex:regexStr_sub_property fileContent:mFileContent options:NSRegularExpressionUseUnicodeWordBoundaries];
            
            if (matches_sub_property) {
                //遍历找到的属性名
                [matches_sub_property enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull matche, NSUInteger idx, BOOL * _Nonnull stop) {
                    
                    NSRange matchRange = [matche range];
                    NSString *matchedString = [mFileContent substringWithRange:matchRange];
                    NSLog(@"matches_sub_property Found match: %@", matchedString);
                    // SmartAIToolsRowView *cell;
                    // SmartAIToolsRowView  *cell = nil;
                    // for (AISysDictDataResultModel *model in result) {
                    
                    if ([matchedString containsString:@"="]) {
                        matchedString = [matchedString componentsSeparatedByString:@"="].firstObject;
                    }
                    
                    if ([matchedString containsString:@"*"]) {
                        matchedString = [matchedString componentsSeparatedByString:@"*"].lastObject;
                        NSString *propertyName = [matchedString stringByReplacingOccurrencesOfString:@" " withString:@""];
                        propertyName = [propertyName stringByReplacingOccurrencesOfString:@";" withString:@""];
                        NSLog(@"局部变量: %@ * %@", className,propertyName);
                        if (![instanceArray containsObject:propertyName]) {
                            [instanceArray addObject:propertyName];
                        }
                    }
                    
                }];
            }
            
        }
        
        //开始改.m文件里对象调用的方法名
        
        //方法传参 对象作为参数，也要获取  正则 =》     :\(GJTTabBar\s{0,3}.\)\w+
        //        NSString *regexStr_params_use = [NSString stringWithFormat:@":\\(%@\\s{0,3}.\\)\\w\\+",className];
        NSString *regexStr_params_use = [NSString stringWithFormat:@":\\(%@ .\\)\\w+",className];
        NSArray<NSTextCheckingResult *> *matches_params_use = [self findResultWithRegex:regexStr_params_use fileContent:mFileContent];
        
        if ([className isEqualToString:@"GJTTabBar"] && [oldFuncNamePrefix containsString:@"addTabBarButtonWithItem"]) {
            
        }
        
        if (matches_params_use){
            
            [matches_params_use enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull matche, NSUInteger idx, BOOL * _Nonnull stop) {
                
                //expression_property matchesInString
                [mFileContent replaceOccurrencesOfString:oldFuncNamePrefix withString:newFuncNamePrefix options:NSCaseInsensitiveSearch range:matche.range];
                
                NSRange matchRange = [matche range];
                NSString *matchedString = [mFileContent substringWithRange:matchRange];
                
                // - (void)addTabButton:(NSString *)barTitle superTabbar:(GJTTabBar *)superTabbar
                // :(GJTTabBar*)superTabbar
                
                if ([matchedString containsString:@")"]) {
                    matchedString = [matchedString componentsSeparatedByString:@")"].lastObject;
                    NSString *propertyName = [matchedString stringByReplacingOccurrencesOfString:@" " withString:@""];
                    // superTabbar
                    if (![instanceArray containsObject:propertyName]) {
                        [instanceArray addObject:propertyName];
                    }
                }
            }];
        }
        
        /// 单例调用
        ///  暂时只支持 [UserManager shareInstance] 格式
        [instanceArray addObject:[NSString stringWithFormat:@"[%@ shareInstance]",className]];
        //类方法调用
        [instanceArray addObject:className];
        
        for (NSString *instanceName in instanceArray) {
            
            [self replaceInstanceFuncNameWithInstanceName:instanceName
                                              fileContent:mFileContent
                                        oldFuncNamePrefix:oldFuncNamePrefix
                                        newFuncNamePrefix:newFuncNamePrefix];
        }
        
        
        [LZFileManager writeContent:mFileContent toFile:mFilePath];
    }
    
}

+ (NSMutableArray <NSString *>*)findInstanceInSuperClassWithClassName:(NSString *)className hFileContent:(NSString *)hFileContent{
    
    NSMutableArray *instanceArray = [NSMutableArray array];
    
    NSString *regexStr_interface = [NSString stringWithFormat:@"@interface.+%@.+:.+",className];
    NSArray<NSTextCheckingResult *> *matches_interface = [self findResultWithRegex:regexStr_interface fileContent:hFileContent];
    if (matches_interface) {
        NSTextCheckingResult *result = matches_interface.firstObject;
        NSString *matchedString = [hFileContent substringWithRange:result.range];
        NSString *superClassName = [[matchedString componentsSeparatedByString:@":"].lastObject stringByReplacingOccurrencesOfString:@" " withString:@""];
        if ([superClassName hasPrefix:@"UI"] || [superClassName hasPrefix:@"NS"]) {
            //继承系统的类，不算有父类
            return nil;
        }
        //父类文件名和类名必须一致 SuperClassName => SuperClassName.h
       NSString *superFilePath = [LZFileManager findFilePath:[LZSpamCodeManager shareInstance].gSourceCodeDir targetFileName:[NSString stringWithFormat:@"%@.h",superClassName]];
        
        NSMutableString *super_hFileContent = [LZFileManager stringWithContentsOfFile:superFilePath];
        NSString *regexStr_property = [NSString stringWithFormat:@"@property\\s+\\(.+%@.+;",className];
        NSArray<NSTextCheckingResult *> *matches_property = [self findResultWithRegex:regexStr_property fileContent:super_hFileContent];
        if (matches_property) {
            //查找父类中这个class的属性
            //但是有可能有多个这个class的属性，比如viewModel1，viewModel2
            //遍历找到的属性名
            [matches_property enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull matche, NSUInteger idx, BOOL * _Nonnull stop) {
                
                NSRange matchRange = [matche range];
                NSString *matchedString = [super_hFileContent substringWithRange:matchRange];
                NSLog(@"matches_property Found match: %@", matchedString);
                //@property (nonatomic, strong) NSString    *   gProjectPath;
                
                NSArray *arr1 = [matchedString componentsSeparatedByString:@"*"];
                if (arr1.count) {
                    NSString *propertyName = [arr1.lastObject stringByReplacingOccurrencesOfString:@" " withString:@""];
                    propertyName = [arr1.lastObject stringByReplacingOccurrencesOfString:@";" withString:@""];
                    NSLog(@"find property: %@ * %@", className,propertyName);
                    if (![instanceArray containsObject:propertyName]) {
                        [instanceArray addObject:propertyName];
                    }
                }
            }];
        }
    }
    if (instanceArray.count) {
        return instanceArray;
    }
    return nil;
}

//判断是否是父类，父类的属性对象更改方法，要同步到子类去
//viewModel => baseClass => subClass
+ (BOOL)isSuperClassWithClassName:(NSString *)className{
    
    if ([className.lowercaseString containsString:@"base"]) {
        return YES;
    }
    return NO;
}

+ (NSArray<NSTextCheckingResult *> *)findResultWithRegex:(NSString *)regexStr fileContent:(NSString *)fileContent{
    return [self findResultWithRegex:regexStr fileContent:fileContent options:NSRegularExpressionUseUnixLineSeparators|NSRegularExpressionAnchorsMatchLines];
}
+ (NSArray<NSTextCheckingResult *> *)findResultWithRegex:(NSString *)regexStr fileContent:(NSString *)fileContent options:(NSRegularExpressionOptions)options{
    
    NSError *error = nil;
    NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:regexStr options:options error:&error];
    NSArray<NSTextCheckingResult *> *matches = [expression matchesInString:fileContent options:0 range:NSMakeRange(0, fileContent.length)];
    
    if (error) {
        NSLog(@"\n正则: %@ \n error:%@\n",regexStr,error);
    }
    
    if (matches.count > 0) {
        return matches;
    }
    
    return nil;
}

// 某个文件中，更改 类调用的原方法 为新方法
+ (void)replaceInstanceFuncNameWithInstanceName:(NSString *)instanceName fileContent:(NSMutableString *)fileContent oldFuncNamePrefix:(NSString *)oldFuncNamePrefix newFuncNamePrefix:(NSString *)newFuncNamePrefix{
    
    //对象方法调用
    NSError *error = nil;
    NSString *regexStr_instance_use = [NSString stringWithFormat:@"\%@ %@:",instanceName,oldFuncNamePrefix];
    if ([instanceName containsString:@"["]) {
        //单例需要多加个转义
        regexStr_instance_use = [NSString stringWithFormat:@"\\%@ %@:",instanceName,oldFuncNamePrefix];
    }
    NSRegularExpression *expression_instance_use = [NSRegularExpression regularExpressionWithPattern:regexStr_instance_use options:NSRegularExpressionUseUnixLineSeparators|NSRegularExpressionAnchorsMatchLines error:&error];
    NSArray<NSTextCheckingResult *> *matches_instance_use = [expression_instance_use matchesInString:fileContent options:NSMatchingReportProgress range:NSMakeRange(0, fileContent.length)];
    
    if (error) {
        NSLog(@"expression_instance_use error : %@",error);
    }
    
    if ([instanceName containsString:@"chatVc"] && [regexStr_instance_use containsString:@"sendQuestionText"]) {
        NSLog(@"单例方法 : %@",regexStr_instance_use);//randomName_92sBspIdEI randomName_J2vfbBkNSu
    }
    
    if (matches_instance_use.count > 0){

        [matches_instance_use enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull matche, NSUInteger idx, BOOL * _Nonnull stop) {
           
            NSString *oldFuncNamePrefix1 = [oldFuncNamePrefix stringByAppendingString:@":"];
            NSString *newFuncNamePrefix1 = [newFuncNamePrefix stringByAppendingString:@":"];
            
//            NSString *oldFuncNamePrefix1 = [NSString stringWithFormat:@")%@:",oldFuncNamePrefix];
//            NSString *newFuncNamePrefix1 = [NSString stringWithFormat:@")%@:",newFuncNamePrefix];
            
            [fileContent replaceOccurrencesOfString:oldFuncNamePrefix1 withString:newFuncNamePrefix1 options:NSCaseInsensitiveSearch range:matche.range];
            
        }];
    }
}

+ (NSString *)randomNewFuncName{
    
    NSUInteger index = arc4random() % __verbs.count;
    NSString *text = __verbs[index];
    
    NSString *randomString = [LZStringRandom randomStringWithLength:3].uppercaseString;
    randomString = [NSString stringWithFormat:@"%@%@",text,randomString];
    if ([randomString containsString:@" "]) {
        randomString = [randomString stringByReplacingOccurrencesOfString:@" " withString:@""];
    }
    if ([randomString containsString:@"\r"]) {
        randomString = [randomString stringByReplacingOccurrencesOfString:@"\r" withString:@""];
    }
    if ([randomString containsString:@"\t"]) {
        randomString = [randomString stringByReplacingOccurrencesOfString:@"\t" withString:@""];
    }
    
    return randomString;
}

static NSArray *__verbs = nil;

+ (void)openVerbsTxt{
    
    NSString *path = [[NSBundle mainBundle] pathForResource:@"verbs" ofType:@"txt"];
    
    NSMutableString *content = [LZFileManager stringWithContentsOfFile:path];
    [content replaceOccurrencesOfString:@"\r\n" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, content.length)];
    NSArray *arr = [content componentsSeparatedByString:@"\t"];
    __verbs = arr;
    
}

@end
